package com.ehome.poct.core.service;

import cn.hutool.core.util.RandomUtil;
import com.ehome.exception.BizException;
import com.ehome.poct.base.api.dto.doctor.ClinicDTO;
import com.ehome.poct.core.api.constant.EhomeConst;
import com.ehome.poct.core.api.dto.message.OriginCheckOrderMsg;
import com.ehome.poct.core.api.dto.message.QueueMessageOriginDTO;
import com.ehome.poct.core.api.dto.order.TestOrderDTO;
import com.ehome.poct.core.api.mapping.CheckEventMapping;
import com.ehome.poct.core.api.virtual.TestOrderService;
import com.ehome.poct.core.constant.OrderBizCodeEnums;
import com.ehome.poct.core.service.rpc.ClinicClient;
import com.ehome.rocketmq.RocketMqTemplate;
import com.google.common.collect.Lists;
import org.junit.jupiter.api.*;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.Mock;
import org.mockito.Mockito;
import org.mockito.junit.jupiter.MockitoExtension;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.List;

import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.mockito.ArgumentMatchers.any;

/**
 * @auther: kuiba.peng
 */
@ExtendWith(MockitoExtension.class)
@DisplayNameGeneration(DisplayNameGenerator.ReplaceUnderscores.class)
public class CheckEventServiceImplTest4SendCheckEvent {

    CheckEventServiceImpl checkEventService;

    @Mock
    TestOrderService testOrderService;

    @Mock
    ClinicClient clinicClient;

    @Mock
    RocketMqTemplate rocketMqTemplate;

    @Mock
    CheckEventMapping checkEventMapping;

    String orderNo;

    String orderId;

    @BeforeEach
    public void setUp() {
        orderNo = "B2211008350046772211100918425958";
        orderId = RandomUtil.randomNumbers(10);
        //checkEventService = new CheckEventServiceImpl(clinicClient, checkEventMapping, rocketMqTemplate);
    }

    @Test
    public void testSendCheckEventSuccess() throws Exception {

        Mockito.when(clinicClient.getById(any())).thenReturn(new ClinicDTO().setSpecialAccountType(0));

        QueueMessageOriginDTO<OriginCheckOrderMsg> queueMessageOriginDTO = new QueueMessageOriginDTO<>();
        queueMessageOriginDTO.setPubAuthor("poct");
        queueMessageOriginDTO.setType(260);
        queueMessageOriginDTO.setTitle("金标仪检测支付完毕订单ID消息");
        queueMessageOriginDTO.setReceivePackageId("com.ehome.check.system.msgprocess");
        String pubTime = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
        OriginCheckOrderMsg checkOrderMsg = new OriginCheckOrderMsg().setOrderId(String.valueOf(orderId));
        queueMessageOriginDTO.setData(checkOrderMsg);
        queueMessageOriginDTO.setPublishTime(pubTime);

        Mockito.when(checkEventMapping.toOrderEvent(any(), any())).thenReturn(queueMessageOriginDTO);
        Mockito.when(rocketMqTemplate.send(any(), any(), any())).thenReturn("success");

        TestOrderDTO orderDTO = new TestOrderDTO().setTestOrderNo(orderNo).setIsPay(Boolean.TRUE)
                .setPayMoney(new BigDecimal(100L)).setPayTime(LocalDateTime.now()).setTestOrderId(Long.valueOf(orderId));
        Mockito.when(testOrderService.list(any())).thenReturn(Lists.newArrayList(orderDTO));

        List<TestOrderDTO> testOrderDTOList = testOrderService.list(null);
        checkEventService.sendCheckEvent(testOrderDTOList.get(0));
    }

    /**
     * 订单信息为空 抛出BizException
     */
    @Test
    public void testSendCheckEventOrderIsNull() {
        BizException bizException = assertThrows(BizException.class, () -> checkEventService.sendCheckEvent(null));
        Assertions.assertEquals(bizException.getMsg(), OrderBizCodeEnums.TEST_ORDER_IS_NULL.getMsg());
    }

    /**
     * 诊所信息为空  消息发送失败
     * result = false
     */
    @Test
    public void testSendCheckEventClinicIsNull() {
        TestOrderDTO orderDTO = new TestOrderDTO().setTestOrderNo(orderNo).setIsPay(Boolean.TRUE)
                .setPayMoney(new BigDecimal(100L)).setPayTime(LocalDateTime.now()).setTestOrderId(Long.valueOf(orderId));
        Mockito.when(testOrderService.list(any())).thenReturn(Lists.newArrayList(orderDTO));

        List<TestOrderDTO> testOrderDTOList = testOrderService.list(null);
        boolean checkEvent = checkEventService.sendCheckEvent(testOrderDTOList.get(0));
        Assertions.assertFalse(checkEvent);
    }

    /**
     * 特殊账号 消息发送失败
     * result = false
     */
    @Test
    public void testSendCheckEventClinicIsSpecialAccount() {
        TestOrderDTO orderDTO = new TestOrderDTO().setTestOrderNo(orderNo).setIsPay(Boolean.TRUE)
                .setPayMoney(new BigDecimal(100L)).setPayTime(LocalDateTime.now()).setTestOrderId(Long.valueOf(orderId));
        Mockito.when(testOrderService.list(any())).thenReturn(Lists.newArrayList(orderDTO));

        Mockito.when(clinicClient.getById(any())).thenReturn(new ClinicDTO().setSpecialAccountType(EhomeConst.SPECIAL_ACCOUNT_TYPE));

        List<TestOrderDTO> testOrderDTOList = testOrderService.list(null);
        boolean checkEvent = checkEventService.sendCheckEvent(testOrderDTOList.get(0));
        Assertions.assertFalse(checkEvent);
    }

    /**
     * 实付金额小于10分 消息发送失败
     * result = false
     */
    @Test
    public void testSendCheckEventPayMoney() {
        TestOrderDTO orderDTO = new TestOrderDTO().setTestOrderNo(orderNo).setIsPay(Boolean.TRUE)
                .setPayMoney(new BigDecimal(1L)).setPayTime(LocalDateTime.now()).setTestOrderId(Long.valueOf(orderId));
        Mockito.when(testOrderService.list(any())).thenReturn(Lists.newArrayList(orderDTO));

        Mockito.when(clinicClient.getById(any())).thenReturn(new ClinicDTO().setSpecialAccountType(0));

        List<TestOrderDTO> testOrderDTOList = testOrderService.list(null);
        boolean checkEvent = checkEventService.sendCheckEvent(testOrderDTOList.get(0));
        Assertions.assertFalse(checkEvent);
    }
}